package com.lt.integration.jpa.component;

import com.lt.integration.jpa.component.common.Direction;
import com.lt.integration.jpa.component.hibernate.Updater;
import com.lt.integration.jpa.page.Pagination;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;

import javax.persistence.metamodel.Attribute;
import java.util.List;
import java.util.Map;

/**
 * 基于jpa的默认jpaRepository实现自己的repository接口
 * NoRepositoryBean 不会创建接口的实例  必须要加这个注解
 *
 * @author weidian
 */
@NoRepositoryBean
public interface BaseDao<T extends BaseModel, QO extends BaseQO> extends JpaRepository<T, Long>, JpaSpecificationExecutor<T> {

	/**
	 * 根据id获取对象 调用findById方法  不条用getOne 延迟加载
	 * @param id
	 * @return T
	 */
	T get(Long id);

	/**
	 * 保存
	 * @param entity
	 * @return
	 */
	T persist(T entity);

	/**
	 * 更新
	 * @param entity
	 * @return T
	 */
	T update(T entity);

	/**
	 * 查询唯一对象
	 *
	 * @param qo
	 * @return
	 */
	T queryUnique(QO qo);

	/**
	 * 查询唯一对象 可查询关联对象
	 *
	 * @param qo
	 * @return
	 */
	T fetchUnique(QO qo);

	/**
	 * 查询对象列表
	 *
	 * @param qo
	 * @return
	 */
	List<T> queryList(QO qo);

	/**
	 * 查询实体列表
	 *
	 * @param qo
	 * @param maxSize		最大获取数量
	 * @return
	 */
	List<T> queryList(QO qo, Integer maxSize);

	/**
	 * 查询实体列表
	 *
	 * @param qo
	 * @param offset		偏移量
	 * @param maxSize		最大获取数量
	 * @return
	 */
	List<T> queryList(QO qo, Integer offset, Integer maxSize);

	/**
	 * 查询实体列表
	 *
	 * @param attributes	查询字段
	 * @param qo
	 * @param offset		偏移量
	 * @param maxSize		最大获取数量
	 * @return
	 */
	List<T> queryList(List<Attribute<?, ?>> attributes,QO qo, Integer offset, Integer maxSize);

	/**
	 * 查询数量
	 *
	 * @param qo
	 * @return
	 */
	Long count(QO qo);

	/**
	 * 分页查询对象
	 * @param qo
	 * @return
	 */
	Pagination<T> queryPagination(QO qo);

	/**
	 * 分页查询对象
	 *
	 * @param pagination
	 * @return
	 */
	Pagination<T> queryPagination(Pagination<T> pagination);

	/**
	 * 根据id的升序或者降序排序
	 * @param id 大于或小于此id的数据
	 * @param qo 查询对象
	 * @return
	 */
	Pagination<T> queryPagination(Long id, QO qo);

	/**
	 * 根据id的升序或者降序排序
	 * @param id 大于或小于此id的数据
	 * @param direction 排序 升序或者降序 默认为 {@link Direction#ASC}
	 * @return
	 */
	Pagination<T> queryPagination(Long id, QO qo, Direction direction);

	/**
	 * 通过updater更新 可以通过updater指定需要更新的字段
	 * @param updater
	 * @return
	 */
	int update(Updater updater);

	/**
	 * 通过updater更新 可以通过updater指定需要更新的字段
	 * @param id id主键
	 * @param attribute 需要更新的字段
	 * @param value 需要更新字段的值
	 * @return
	 */
	int update(Long id, Attribute<?, ?> attribute, Object value);

	/**
	 * 通过updater更新 可以通过updater指定需要更新的字段
	 * @param id id主键
	 * @param params 需要更新字段的map
	 * @return
	 */
	int update(Long id, Map<Attribute<?, ?>, Object> params);

	/**
	 * 批量删除
	 */
	void batchDelete(List<T> entities);

    /**
     * 批量保存
     * @param entities
     * @return
     */
    Iterable<T> batchSave(Iterable<T> entities);

    /**
     * 批量更新
     * @param entities
     * @return
     */
    Iterable<T> batchUpdate(Iterable<T> entities);

	/**
	 * 是否存在
	 * @param qo
	 * @return
	 */
	boolean exists(QO qo);


}
